package com.example.docking.service.impl;

import com.example.docking.dao.jindie.GenericDataItem;
import com.example.docking.dao.jindie.ResponseData;
import com.example.docking.dao.jindie.request.CommonOperateDao;
import com.example.docking.dao.jindie.request.MaterialDataRequest;
import com.example.docking.dao.jindie.request.PurRequestDataRequest;
import com.example.docking.dao.jindie.response.MaterialData;
import com.example.docking.dao.jindie.response.MaterialEntity;
import com.example.docking.dao.jindie.response.SaveData;
import com.example.docking.dao.jindie.response.SupplierData;
import com.example.docking.dao.jindie.response.motaskbill.SubMaterialEntity;
import com.example.docking.dao.jingxin.request.ApplyOrderWcqd;
import com.example.docking.dao.jingxin.request.ApplyOrderWgqd;
import com.example.docking.dao.jingxin.request.ApplyOrderWxqd;
import com.example.docking.service.PurRequestService;
import com.example.docking.util.Constants;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.smecloud.apigw.model.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;

/**
 * @ClassName PurRequestServiceImpl
 * @Description 需求：敬信数据过来的采购申请单处理  多线程处理
 * @Author zhanghuiping
 * @Date 2025 - 05 - 06 02:31:51
 */

@Slf4j
public class PurRequestServiceImpl extends BaseServiceImpl implements PurRequestService {
    private static final Logger logger = LoggerFactory.getLogger(PurRequestServiceImpl.class);
    private static final int THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors();
    private final ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
    private final Gson gson = new Gson();

    @Override
    public ResponseData InsertPurRequestWcqd(String emp, String task_no, List<ApplyOrderWcqd> applyOrderWcqdList, List<SubMaterialEntity> subMaterialEntityList, String id) {
        return processRequest(emp, task_no, applyOrderWcqdList, subMaterialEntityList, "外采", "Insert PurRequestWcqd", id);
    }

    @Override
    public ResponseData InsertPurRequestWgqd(String Emp, String task_no, List<ApplyOrderWgqd> applyOrderWgqdList, List<SubMaterialEntity> subMaterialEntityList, String id) {
        return processRequest(Emp, task_no, applyOrderWgqdList, subMaterialEntityList, "外购", "Insert PurRequestWgqd", id);
    }

    @Override
    public ResponseData InsertPurRequestWxqd(String Emp, String task_no, List<ApplyOrderWxqd> applyOrderWxqdList, List<SubMaterialEntity> subMaterialEntityList, String id) {
        return processRequest(Emp, task_no, applyOrderWxqdList, subMaterialEntityList, "外协", "Insert PurRequestWxqd", id);
    }

    /**
     * @MethodName InsertPurRequestSCDD
     * @Parameters 销售订单非自制的生成采购申请单
     * @Author zhanghuiping
     * @Date 2025 - 05 - 06 02:45:26
     */


    @Override
    public ResponseData InsertPurRequestSCDD(String Emp_id, String sall_no, List<MaterialEntity> materialEntityList) {
        logger.info("InsertPurRequestSCDD:sall_no={}", sall_no);
        logger.info("InsertPurRequestSCDD:Emp_id={}", sall_no);

        ResponseData responseDataresult = new ResponseData();
        DataServiceImpl service = new DataServiceImpl();
        PurRequestDataRequest purRequestDataRequest = new PurRequestDataRequest();
        int page = 1; // 初始页码
        int pageSize = 10; // 每页记录数
        HashMap<String, String> map = new HashMap<>();
        map.put("page", String.valueOf(page));
        map.put("page_size", String.valueOf(pageSize));
        // 单据日期
        Date currentDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String formattedDate = sdf.format(currentDate);

        // 使用 Calendar 类加一天
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        Date nextDay = calendar.getTime();
        String nextDayFormatted = sdf.format(nextDay);

        purRequestDataRequest.setBill_date(formattedDate); // 当前日期为单据日期
        purRequestDataRequest.setRemark(sall_no);

        // 建议供应商：whole_supplier_id 外采 外协 外购
        // 供应商 id  供应商编码  默认值
        SupplierServiceImpl departmentService = new SupplierServiceImpl();
        SupplierData supplierData = null;


        try {
            supplierData = departmentService.getSupplier(service, "销售非自制");
            purRequestDataRequest.setWhole_supplier_id(supplierData.getId());
            purRequestDataRequest.setEmp_id(Emp_id);
            purRequestDataRequest.setMaterial_entity(materialEntityList);
            ApiResult result1 = service.InsertDataOne(Constants.PUR_REQUEST, map, purRequestDataRequest);

            Type type1 = new TypeToken<ResponseData<SaveData>>() {
            }.getType();
            ResponseData<SaveData> response1 = gson.fromJson(result1.getBody(), type1);
            logger.info("Code: {}", response1.getErrcode());
            logger.info("Message: {}", response1.getDescription());
            logger.info("data: {}", response1.getData());
            responseDataresult = response1;
        } catch (Exception e) {
            logger.error("{}：处理采购申请单时发生异常", e);
            responseDataresult.setErrcode(10003);
            responseDataresult.setDescription("处理采购申请单时发生异常");
        }
        return responseDataresult;
    }


    private <T> ResponseData processRequest(String emp, String task_no, List<T> applyOrderList, List<SubMaterialEntity> subMaterialEntityList, String supplierType, String logMsg, String id) {
        logger.info("PurRequestServiceImpl-{}：{}", logMsg, logMsg);
        ResponseData responseDataresult = new ResponseData();
        DataServiceImpl service = new DataServiceImpl();
        PurRequestDataRequest purRequestDataRequest = new PurRequestDataRequest();
        int page = 1; // 初始页码
        int pageSize = 10; // 每页记录数
        HashMap<String, String> map = new HashMap<>();
        map.put("page", String.valueOf(page));
        map.put("page_size", String.valueOf(pageSize));
        //id 有值修改 无值 增加
        logger.info("id=======" + id);
        if (id != null && !id.equals("")) {
            purRequestDataRequest.setId(id);
        }
        // 单据日期
        Date currentDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String formattedDate = sdf.format(currentDate);

        // 使用 Calendar 类加一天
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        Date nextDay = calendar.getTime();
        String nextDayFormatted = sdf.format(nextDay);

        purRequestDataRequest.setBill_date(formattedDate); // 当前日期为单据日期
        purRequestDataRequest.setRemark(task_no);

        // 建议供应商：whole_supplier_id 外采 外协 外购
        // 供应商 id  供应商编码  默认值
        SupplierServiceImpl departmentService = new SupplierServiceImpl();
        SupplierData supplierData = null;
        // emp
        EmpServiceImpl empService = new EmpServiceImpl();
        String emp_id = null;

        try {
            supplierData = departmentService.getSupplier(service, supplierType);
            purRequestDataRequest.setWhole_supplier_id(supplierData.getId());
            // 商品分录
            emp_id = empService.getEmpId(service, emp);
            purRequestDataRequest.setEmp_id(emp_id);

            List<MaterialEntity> materialEntities = new ArrayList<>();
            List<Future<ProcessResult>> futures = new ArrayList<>();

            for (Object applyOrder : applyOrderList) {
                Callable<ProcessResult> task = () -> processApplyOrder(applyOrder, nextDayFormatted, service);
                futures.add(executorService.submit(task));
            }

            for (Future<ProcessResult> future : futures) {
                try {
                    ProcessResult result = future.get();
                    handleProcessResult(result, subMaterialEntityList, materialEntities, service, logMsg);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    logger.error("{}：线程被中断", logMsg, e);
                    responseDataresult.setErrcode(10001);
                    responseDataresult.setDescription("线程被中断");
                    break;
                } catch (ExecutionException e) {
                    logger.error("{}：线程执行异常", logMsg, e.getCause());
                    responseDataresult.setErrcode(10002);
                    responseDataresult.setDescription("线程执行异常");
                    break;
                }
            }

            if (responseDataresult.getErrcode() == 0) {
                purRequestDataRequest.setMaterial_entity(materialEntities);
                ApiResult result1 = service.InsertDataOne(Constants.PUR_REQUEST, map, purRequestDataRequest);
                responseDataresult = handleInsertResult(result1, logMsg);

                // 审核
                auditPurRequest(result1, service);
            }
        } catch (Exception e) {
            logger.error("{}：处理采购申请单时发生异常", logMsg, e);
            responseDataresult.setErrcode(10003);
            responseDataresult.setDescription("处理采购申请单时发生异常");
        }

        logger.info("{}返回：responseDataresult{}", logMsg, responseDataresult);
        return responseDataresult;
    }

    /**
     * 采购订单审核
     *
     * @param insertResult
     * @param service
     */
    private void auditPurRequest(ApiResult insertResult, DataServiceImpl service) {
        ResponseData<SaveData> response = gson.fromJson(insertResult.getBody(), new TypeToken<ResponseData<SaveData>>() {
        }.getType());
        if (response.getErrcode() == 0) {
            log.info("采购申请单推送ERP成功");
            List<String> ids = response.getData().getIds();
            CommonOperateDao commonOperateDao = new CommonOperateDao();
            commonOperateDao.setEntity_number(Constants.PUR_BILL_REQUEST);
            commonOperateDao.setIds(ids);
            commonOperateDao.setOperate_type(Constants.AUDIT);
            try {
                ApiResult auditData = service.SelectDataAudit(Constants.COMMON_OPERATE, new HashMap<>(), commonOperateDao);
                ResponseData<SaveData> auditResponse = gson.fromJson(auditData.getBody(), new TypeToken<ResponseData<SaveData>>() {
                }.getType());
                if (auditResponse.getErrcode() == 0) {
                    log.info("审核采购申请单成功, auditResponse = {}", auditResponse);
                } else {
                    log.error("审核采购申请单失败. auditResponse: {}", auditResponse);
                    throw new RuntimeException(auditResponse.getErrcode() + ":" + auditResponse.getDescription());
                }
            } catch (Exception e) {
                log.error("Error occurred while auditing sales order", e);
                throw new RuntimeException(e);
            }
        }
    }

    private ProcessResult processApplyOrder(Object applyOrder, String nextDayFormatted, DataServiceImpl service) {
        SubMaterialEntity subMaterialEntity = new SubMaterialEntity();
        MaterialEntity materialEntity = new MaterialEntity();

        if (applyOrder instanceof ApplyOrderWcqd) {
            ApplyOrderWcqd wcqd = (ApplyOrderWcqd) applyOrder;
            populateEntities(subMaterialEntity, materialEntity, wcqd.getPartName(), wcqd.getPartDrawingNo(), wcqd.getQuantity(), wcqd.getId(), "外采");
        } else if (applyOrder instanceof ApplyOrderWgqd) {
            ApplyOrderWgqd wgqd = (ApplyOrderWgqd) applyOrder;
            populateEntities(subMaterialEntity, materialEntity, wgqd.getPartName(), wgqd.getPartDrawingNo(), wgqd.getQuantity(), wgqd.getId(), "外购");
        } else if (applyOrder instanceof ApplyOrderWxqd) {
            ApplyOrderWxqd wxqd = (ApplyOrderWxqd) applyOrder;
            populateEntities(subMaterialEntity, materialEntity, wxqd.getPartName(), wxqd.getPartDrawingNo(), wxqd.getOutsourcingQuantity(), wxqd.getId(), "外协");
        }


        materialEntity.setDelivery_date(nextDayFormatted);
        int page = 1; // 初始页码
        int pageSize = 10; // 每页记录数
        HashMap<String, String> map = new HashMap<>();
        map.put("page", String.valueOf(page));
        map.put("page_size", String.valueOf(pageSize));
        map.put("search", materialEntity.getMaterial_number());
        logger.info("materialNumber: " + materialEntity.getMaterial_number());
        ApiResult detailMateria = null;
        try {
            detailMateria = service.SelectDataList(Constants.MATERIAL_PATH, map, "");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        Type MateriaDataType = new TypeToken<ResponseData<GenericDataItem<MaterialData>>>() {
        }.getType();
        ResponseData<GenericDataItem<MaterialData>> detailMateriaData = gson.fromJson(detailMateria.getBody(), MateriaDataType);
        logger.info("detailMateriaData: " + detailMateriaData);

        return new ProcessResult(subMaterialEntity, materialEntity, detailMateriaData);
    }

    private void populateEntities(SubMaterialEntity subMaterialEntity, MaterialEntity materialEntity, String partName, String partDrawingNo, double quantity, String id, String orderType) {
        subMaterialEntity.setDen_qty_scrap("1");
        subMaterialEntity.setNum_qty_scrap("1");
        subMaterialEntity.setSub_material_name(partName);
        subMaterialEntity.setSub_material_number(partDrawingNo);
        subMaterialEntity.setSub_qty(quantity);
        materialEntity.setMaterial_name(partName);
        materialEntity.setMaterial_number(partDrawingNo);
        materialEntity.setApply_qty(quantity);
        materialEntity.setComment(id + ":" + orderType);//行备注 存敬信的id 传给敬信需要
    }

    private void handleProcessResult(ProcessResult result, List<SubMaterialEntity> subMaterialEntityList, List<MaterialEntity> materialEntities, DataServiceImpl service, String logMsg) {
        SubMaterialEntity subMaterialEntity = result.getSubMaterialEntity();
        MaterialEntity materialEntity = result.getMaterialEntity();
        ResponseData<GenericDataItem<MaterialData>> detailMateriaData = result.getDetailMateriaData();

        if (detailMateriaData.getErrcode() == 0) {
            GenericDataItem<MaterialData> genericDataItemMaterial = detailMateriaData.getData();
            List<MaterialData> materialData = genericDataItemMaterial.getRows();
            boolean flag = false;
            if (materialData.size() > 0) {
                for (MaterialData materialData1 : materialData) {
                    if (materialData1.getNumber().equals(materialEntity.getMaterial_number())) {
                        flag = true;
                        materialEntity.setMaterial_id(materialData1.getId());
                        materialEntity.setMaterial_name(materialData1.getName());
                        materialEntity.setUnit_id(materialData1.getBase_unit_id());
                        subMaterialEntity.setSub_unit_id(materialData1.getBase_unit_id());
                        subMaterialEntity.setSub_material_id(materialData1.getId());
                    }
                }
            }
            if (!flag) {
                createNewMaterial(materialEntity, subMaterialEntity, service, logMsg);
            }
            subMaterialEntityList.add(subMaterialEntity);
            materialEntities.add(materialEntity);
        } else {
            logger.error("{}：获取商品数据失败. Errcode: {}, Description: {}", logMsg, detailMateriaData.getErrcode(), detailMateriaData.getDescription());
        }
    }

    private void createNewMaterial(MaterialEntity materialEntity, SubMaterialEntity subMaterialEntity, DataServiceImpl service, String logMsg) {
        MaterialDataRequest materialDataRequest = new MaterialDataRequest();
        materialDataRequest.setName(materialEntity.getMaterial_name());
        materialDataRequest.setNumber(materialEntity.getMaterial_number());
        materialDataRequest.setIgnore_warn(true);
        MeasureUnitServiceImpl measureUnitService = new MeasureUnitServiceImpl();
        String unit_id = null;
        try {
            unit_id = measureUnitService.getMeasureUnitId(service, "");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        materialDataRequest.setBase_unit_id(unit_id);
        HashMap<String, String> map = new HashMap<>();
        ApiResult materialResult1 = null;
        try {
            materialResult1 = service.InsertDataOne(Constants.MATERIAL_PATH, map, materialDataRequest);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        Type SaveDataType = new TypeToken<ResponseData<SaveData>>() {
        }.getType();
        logger.info("{}：插入新商品", logMsg);
        ResponseData<SaveData> responseData = gson.fromJson(materialResult1.getBody(), SaveDataType);
        logger.info("Code: {}", responseData.getErrcode());
        logger.info("Message: {}", responseData.getDescription());
        logger.info("data: {}", responseData.getData());
        if (responseData.getErrcode() == 0) {
            SaveData saveData = responseData.getData();
            materialEntity.setMaterial_id(saveData.getIds().get(0));
            materialEntity.setMaterial_name(materialEntity.getMaterial_name());
            materialEntity.setUnit_id(unit_id);
            subMaterialEntity.setSub_unit_id(unit_id);
            subMaterialEntity.setSub_material_id(saveData.getIds().get(0));
        } else {
            logger.error("{}：插入新商品失败. Errcode: {}, Description: {}", logMsg, responseData.getErrcode(), responseData.getDescription());
        }
    }

    private ResponseData handleInsertResult(ApiResult result1, String logMsg) {
        Type type1 = new TypeToken<ResponseData<SaveData>>() {
        }.getType();
        ResponseData<SaveData> response1 = gson.fromJson(result1.getBody(), type1);
        if (response1.getErrcode() == 0) {
            logger.info("{}：保存成功", logMsg);
            logger.info("Code: {}", response1.getErrcode());
            logger.info("Message: {}", response1.getDescription());
            logger.info("data: {}", response1.getData());
            return response1;
        } else {
            logger.error("{}：插入采购申请单失败. Errcode: {}, Description: {}", logMsg, response1.getErrcode(), response1.getDescription());
            return response1;
        }
    }

    // 在服务关闭时调用此方法关闭线程池
    public void shutdownExecutorService() {
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }

    // 自定义结果类，用于存储线程处理结果
    private static class ProcessResult {
        private final SubMaterialEntity subMaterialEntity;
        private final MaterialEntity materialEntity;
        private final ResponseData<GenericDataItem<MaterialData>> detailMateriaData;

        public ProcessResult(SubMaterialEntity subMaterialEntity, MaterialEntity materialEntity, ResponseData<GenericDataItem<MaterialData>> detailMateriaData) {
            this.subMaterialEntity = subMaterialEntity;
            this.materialEntity = materialEntity;
            this.detailMateriaData = detailMateriaData;
        }

        public SubMaterialEntity getSubMaterialEntity() {
            return subMaterialEntity;
        }

        public MaterialEntity getMaterialEntity() {
            return materialEntity;
        }

        public ResponseData<GenericDataItem<MaterialData>> getDetailMateriaData() {
            return detailMateriaData;
        }
    }
}